/**
 * Copyright (c) 2018-2028, LookAhead.
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.lookahead.parent.database.base;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.lookahead.parent.apidoc.db.BaseEntity;
import org.lookahead.parent.common.secure.Userinfo;
import org.lookahead.parent.common.utils.SecureUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 业务封装基础类
 *
 * @param <M> mapper
 * @param <T> model
 * @author LookAhead
 */
@Validated
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements BaseService<T> {

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean save(T entity) {
        Userinfo user = SecureUtil.getUser();
        if (user != null) {
            entity.setOperatorBy(user.getUserId());
            entity.setOperatorName(user.getRealName());
        }
        Date now = new Date();
        entity.setGmtCreate(now);
        entity.setGmtModified(now);

        entity.setIsDeleted(0);
        return super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateById(T entity) {
        Userinfo user = SecureUtil.getUser();
        if (user != null) {
            entity.setOperatorBy(user.getUserId());
            entity.setOperatorName(user.getRealName());
        }
        entity.setGmtModified(DateUtil.date());
        return super.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean deleteLogic(@NotEmpty List<Long> ids) {
        return super.removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveBatch(Collection<T> entityList) {
        Userinfo user = SecureUtil.getUser();
        Date now = new Date();
        entityList.forEach(entity -> {
            if (user != null) {
                entity.setOperatorBy(user.getUserId());
                entity.setOperatorName(user.getRealName());
            }
            entity.setGmtCreate(now);
            entity.setGmtModified(now);
            entity.setIsDeleted(0);
        });
        return super.saveBatch(entityList);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateBatchById(Collection<T> entityList) {
        Userinfo user = SecureUtil.getUser();
        Date now = new Date();
        entityList.forEach(entity -> {
            if (user != null) {
                entity.setOperatorBy(user.getUserId());
                entity.setOperatorName(user.getRealName());
            }
            entity.setGmtModified(now);
        });
        return super.updateBatchById(entityList);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveOrUpdate(T entity) {
        Userinfo user = SecureUtil.getUser();
        if (user != null) {
            entity.setOperatorBy(user.getUserId());
            entity.setOperatorName(user.getRealName());
        }
        entity.setGmtModified(DateUtil.date());
        return super.saveOrUpdate(entity);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
        Userinfo user = SecureUtil.getUser();
        if (user != null) {
            entity.setOperatorBy(user.getUserId());
            entity.setOperatorName(user.getRealName());
        }
        Date now = new Date();
        entity.setGmtCreate(now);
        entity.setGmtModified(now);
        entity.setIsDeleted(0);
        return super.saveOrUpdate(entity, updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        Userinfo user = SecureUtil.getUser();
        Date now = new Date();
        entityList.forEach(entity -> {
            if (user != null) {
                entity.setOperatorBy(user.getUserId());
                entity.setOperatorName(user.getRealName());
            }
            entity.setGmtModified(now);
        });
        return super.saveOrUpdateBatch(entityList, batchSize);
    }
}
